home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / generic / generic.doc < prev    next >
Encoding:
Text File  |  1994-08-02  |  13.2 KB  |  353 lines

  1.  
  2.  
  3.                           Generic Application Template
  4.                                  (preliminary)
  5.                                    Tom Davis
  6.                                December 13, 1991
  7.     
  8.     Many applications, such as text editors, drawing packages, paint
  9.     programs, and word processors have a similar form.  The user reads a
  10.     file, modifies it, and writes the results.  Unfortunately, this model
  11.     can get quite complicated.  What if the user hasn't got write
  12.     permission?  What if there is some I/O error on the write?  What if the
  13.     user hasn't yet specified a name?  Is the user in view-only mode?
  14.     
  15.     The generic application will provide a file opening template that is
  16.     reasonable, but which can be modified by users.  For example, the
  17.     generic application goes into view_only mode if an unwriteable file is
  18.     loaded.  Some applications may want to do otherwise.
  19.     
  20.     The generic application will work on all machines, in singlebuffer or
  21.     doublebuffer modes, and in RGB or color-index modes.
  22.     
  23.     The generic program will catch various quit and kill signals from UNIX
  24.     and the window manager, and should treat them appropriately.  This
  25.     behavior is optional.
  26.     
  27.     The application is as user-interface-free as possible.  It uses the
  28.     showcase libui to make pulldown menues and the confirmer dialog box. 
  29.     Both can be removed/replaced easily.  To collect a file name it uses 
  30.     the showcase browse gizmo, but the file name collection routine can be
  31.     replaced.
  32.     
  33.     The "guts" of the generic application is a program that draws a black
  34.     window and draws a red cross on it.
  35.     
  36.     What follows is a description of what the generic application does,
  37.     followed by a description of how to port your own application to this
  38.     template.  I'm very interested in feedback and improvements.
  39.     
  40.     ----------
  41.     
  42.     The following state is maintained:
  43.     
  44.             directory from which the application was launched
  45.             the application's current directory
  46.             whether the application is in view_only mode
  47.             the current file name (or NONE, if there isn't one)
  48.             whether the file has been modified
  49.             is the application making checkpoint (see definitions) files
  50.             is the application making backup (see definitions) files
  51.     
  52.     ----------
  53.     
  54.     Pull-down menus:
  55.     
  56.     The generic application will provide a pull-down menu containing the
  57.     following commands:
  58.     
  59.             NEW
  60.             OPEN
  61.             SAVE
  62.             SAVE AS
  63.             INSERT
  64.             PRINT
  65.             QUIT
  66.     
  67.     NEW:
  68.     
  69.     In VIEW_ONLY mode, the command is not allowed.
  70.     
  71.     A dirty-file check (see definitions) is performed.
  72.     
  73.     If the NEW command is not aborted, the current file's data is cleared,
  74.     the application is taken out of view_only mode, and the current file
  75.     name is set to NONE.  The dirty_file flag is cleared.
  76.     
  77.     OPEN:
  78.     
  79.     A dirty-file check (see definitions) is performed.
  80.     
  81.     If the OPEN command is not aborted, a new file name is obtained, and
  82.     the open-status (see definitions) of the file with the name collected
  83.     is checked.
  84.     
  85.     If the file name collection fails, abort the OPEN command.
  86.     
  87.     If the file does not exist or cannot be read:
  88.     
  89.             In VIEW_ONLY mode, abort the OPEN command.
  90.     
  91.             If the user cannot create a file with that name, or if the
  92.             file already exists, but cannot be read, the OPEN command
  93.             is aborted.
  94.     
  95.             The dirty_file flag is cleared.
  96.     
  97.             The data in the buffer is cleared.
  98.     
  99.             If the user can create such a file, view_only mode is turned
  100.             off, and the current file name is set to the new name.
  101.     
  102.     If the file does exist and can be read:
  103.     
  104.             The dirty_file flag is cleared.
  105.     
  106.             The data in the buffer is cleared.
  107.     
  108.             If it cannot be written, the user is informed, view_only mode
  109.             is turned on, and the file name is set to the given name.
  110.     
  111.             If it can be written, view_only mode is turned off, unless
  112.             VIEW_ONLY mode is on, and the file name is set to the given
  113.             name.
  114.     
  115.             Read the file.
  116.     
  117.     SAVE:
  118.     
  119.     In VIEW_ONLY mode, the command is aborted.
  120.     
  121.     If the current file name is NONE, collect a file name.  Find its
  122.     open-status.  If it can't be written or created, or if the collection
  123.     fails, inform the user and abort.
  124.     
  125.     If there was a current file, check its open-status, possibly resetting
  126.     the view_only flag.  If the file can't be written or created, inform 
  127.     the user and abort.
  128.     
  129.     The buffer is written to a file with the current file name.  If no 
  130.     error occurs, the dirty flag is turned off.
  131.     
  132.     SAVE-AS:
  133.     
  134.     (This command works in VIEW_ONLY mode.)
  135.     
  136.     A file name is collected, and its open-status is determined.  If the
  137.     collection of the name fails, abort the SAVE-AS command.
  138.     
  139.     If the file exists but can't be written, or if it does not exist and
  140.     cannot be created, the user is informed, and the command aborts.
  141.     
  142.     Otherwise, write the file.  If no write error occurs, clear the
  143.     dirty_flag, and unless VIEW_ONLY mode is turned on, set the current
  144.     file name to the new name, and turn view_only mode off.
  145.     
  146.     INSERT:
  147.     
  148.     In view-only mode, abort.
  149.     
  150.     Collect a file name and check its open-status.
  151.     
  152.     If the collection fails, abort the INSERT command.
  153.     
  154.     If the file exists and can be read, call the user routine that inserts
  155.     the contents of the file.  Presumably, this sets the dirty flag.
  156.     
  157.     PRINT:
  158.     
  159.     A print file name is generated from the user's PID and a counter.  The
  160.     open status of $TMPDIR/filename is determined.  If it can be written 
  161.     or created, the user's print routine is called with the file name.  It 
  162.     is up to the print command to issue the lp command or whatever.
  163.     
  164.     QUIT:
  165.     
  166.     A dirty-file check (see definitions) is performed.
  167.     
  168.     Unless the QUIT command is aborted, the program exits.
  169.     
  170.     ----------
  171.     
  172.     Startup:
  173.     
  174.     The application is invoked as:
  175.     
  176.         genericapplication -[vf] [filename]
  177.     
  178.     If the -v flag is set, the application is started in VIEW_ONLY mode.  
  179.     If the -f flag is specified, the application is started in the 
  180.     foreground to aid in both debugging and for use in certain other 
  181.     conditions.
  182.     
  183.     If the application is in VIEW_ONLY mode, a file name must be specified
  184.     and the file must be readable, or there's an error, and the 
  185.     application just won't start up.
  186.     
  187.     If a filename is specified, it is exactly the same as if the 
  188.     application were opened, the open command issued, and the given file 
  189.     name was collected.
  190.     
  191.     If no filename is specified, the current file name is set to NONE.
  192.     
  193.     ----------
  194.     
  195.     Signals:
  196.     
  197.     The generic application will catch the common UNIX signals.  When
  198.     caught, the user will be informed of the error, and be given a chance
  199.     to save the contents of the buffer.
  200.     
  201.     If the application recieves a WINQUIT or WINSHUT command, it should be
  202.     treated in exactly the same way as a QUIT command.
  203.     
  204.     ----------
  205.     
  206.     Backup and Checkpoint files:
  207.     
  208.     The user code sets the flags MAKE_BACKUPS and MAKE_CHECKPOINTS.  Each
  209.     time a NEW or OPEN command is issued, internal variables called
  210.     "make_backups" and "make_checkpoints" are set that are true only if
  211.     creation/writing of those files should be done.
  212.     
  213.     ----------
  214.     
  215.     Utility commands:
  216.     
  217.     void resizepulldowns();
  218.     long getfileopenstatus(char *filename);
  219.     
  220.     /* getfileopenstatus() returns a mask with the following bits
  221.      * (more may follow):
  222.      *
  223.      * #define FILE_EXISTS           1
  224.      * #define CAN_WRITE_FILE        2
  225.      */
  226.     
  227.     Visible flags:
  228.     
  229.     VIEW_ONLY, view_only
  230.     MAKE_BACKUPS, make_backups
  231.     MAKE_CHECKPOINTS, make_checkpoints
  232.     dirty_file
  233.     
  234.     Visible variables:
  235.     
  236.     char *currentfilename;
  237.     
  238.     User-supplied routines:
  239.     
  240.     void clearbuffer();
  241.     long readfile(char *filename);
  242.     long makebackupname(char *backupname, const char *filename);
  243.     long makecheckpointname(char *checkpointname, const char *filename);
  244.     long writefile(char *filename);
  245.     long insertfile(char *filename);
  246.     long printfile(char *printfilename);
  247.     long errorwritefile(char *filename);
  248.     /* errorwritefile() may be identical to writefile(), but it may want
  249.      * to take into account possible internal data corruption.
  250.      */
  251.     void help();
  252.     /* help() is the command called if the user asks for generic help. */
  253.     
  254.     ----------
  255.     
  256.     Definitions:
  257.     
  258.     backup file: A copy of the original file saved when the original
  259.     is read.  It typically has an extension like ".bak", and is written in
  260.     the same directory as the original file.
  261.     
  262.     buffer: This refers to the data stored in the program's internal data
  263.     structures, as opposed to what is saved in a file.
  264.     
  265.     checkpoint file: A version of the file that is occasionally written to
  266.     disk automatically to prevent against errors.  It typically has an
  267.     extension like ".ckp", and is written in the same directory as the
  268.     original file.
  269.     
  270.     collecting a file name: In the generic application, the showcase
  271.     browsegizmo is used to get a file name and perhaps a new directory path.
  272.     If '~' appears in the name, it is expanded.  The collection of a name
  273.     can fail if the user presses the equivalent of a "Cancel" button.
  274.     
  275.     dirty-file check: If the current file has no modifications, nothing is
  276.     done.  If it is modified, the user is asked about saving the changes. 
  277.     His options are "Yes" (save the changes and continue the command), "No"
  278.     (throw away the changes and continue the command), and "Cancel" (abort
  279.     the command).
  280.     
  281.     file names: relative directory paths and the '~' character may be used
  282.     in file names.
  283.     
  284.     open-status: The open-status includes: Does the user have read
  285.     permission on the file? Write permission? Does the file exist?  If not,
  286.     can the user create a file in that directory?
  287.     
  288.     read the file: Determine the values of the flags make_backups and
  289.     make_checkpoints.  If make_backups is set, call the user routine that
  290.     makes a backup file.  The file is read, and any errors are reported to 
  291.     the user.  1 is returned on success; 0 on failure.  It is up to the
  292.     user-supplied reading command to decide what to do with the buffer's
  293.     contents in the event of some read error; perhaps it will be cleared,
  294.     or perhaps as much valid data as possible is retained.
  295.     
  296.     view-only mode: There are two levels of view-only.  The application can
  297.     be opened in VIEW_ONLY mode, in which case no changes can be made to
  298.     the buffer.  If the application is not in this generic VIEW_ONLY mode,
  299.     there may be times when edits are disallowed anyway -- for example if
  300.     the file currently loaded is unwriteable.  The flag for this secondary
  301.     level is called "view_only" (lower case).  Inside the application, only
  302.     the view_only flag needs to be examined.  If VIEW_ONLY is true,
  303.     view_only will always be true.
  304.     
  305.     write the file: Try to write the current data to the currently-opened
  306.     file.  Return 0 if any write-error occurs.  Provide as much feedback as
  307.     possible about the cause of the error.
  308.     
  309.     ----------
  310.     
  311.     Using the generic application.
  312.     
  313.     Most of your changes will be to the file application.c, but if you want
  314.     to use the pull-down menues, you will probably want to add entries in
  315.     pulldown.c, and if you want additional speed keys (alt-something), you
  316.     will want to mess with doexec.c.
  317.     
  318.     If you need to make significant changes to the other files, let me know.
  319.     I tried to keep things as generic as possible.
  320.     
  321.     To compile with the pulldown menu or the generic confirmer, you'll need
  322.     the showcase libui.a library.  There's a working version in
  323.     bedlam.asd:~davis/libui/libui.a.
  324.     
  325.     The simplest port involves rewriting mainloop(), initgraphics(),
  326.     handleredraw(), and providing routines for readfile(), writefile(), etc.
  327.     If your application does not do some of the things like printing,
  328.     file insertion, etc., simply put a zero in the appropriate slot in
  329.     the structure called entries.
  330.     
  331.     Read the comments in application.c -- they give a pretty good idea of
  332.     its structure.
  333.     
  334.     If you want to use a gizmo, the code for a generic gizmo is in the
  335.     subdirectory called gizmos.  In the generic program, the gizmo is
  336.     capable of sending a single command -- TOUCHME.  Use any interface you
  337.     like in the gizmo.  Unfortuantely, the gizmo documentation isn't very
  338.     good.
  339.     
  340.     ----------
  341.     
  342.     Possible Future Improvements:
  343.     
  344.     It would be nice if the user had the option to either overwrite the file
  345.     or write a copy and then rename it to be the new file (if that's
  346.     possible).  For now, it isn't.  For this to work, the code must be
  347.     careful to preserve file permissions, and watch out for files with
  348.     multible links.
  349.     
  350.     Provide a reopen file list for quick access to old file names.
  351.     
  352.     It would be good to have a generic WorkSpace icon.
  353.